package com.djhu.freepartner.web.control.advice;


import com.djhu.freepartner.core.RestRsp;
import com.djhu.freepartner.core.Status;
import com.djhu.freepartner.core.exception.ServiceException;
import com.djhu.freepartner.web.support.BaseControl;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


/**
 * 所有异常响应 ResponseCode 均为200(@ResponseStatus(HttpStatus.OK)),防止部分路由器(小米路由器)或者浏览器的劫持
 * @author KevinBlandy
 */
@ControllerAdvice
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public class ExceptionAdvice extends BaseControl {
	
	public static final String ERROR_VIEW = "/error/error";
	
	/**
	 * 异常处理
	 * @param request
	 * @param response
	 * @return
	 * @throws IOException
	 */
	public RestRsp errorHandle(HttpServletRequest request, HttpServletResponse response, RestRsp restRsp) throws IOException {

		return restRsp;
	}
	
	/**
	 * 缺少必须参数
	 * @param request
	 * @param response
	 * @param e
	 * @return
	 * @throws IOException 
	 */
	@ExceptionHandler(MissingServletRequestParameterException.class)
	public RestRsp missingServletRequestParameterException(HttpServletRequest request, HttpServletResponse response, MissingServletRequestParameterException e) throws IOException {
		RestRsp restRsp = new RestRsp();
		restRsp.setCode(Status.MISSING_REQUEST_PARAM.getCode());
		restRsp.setMsg(Status.MISSING_REQUEST_PARAM.getDesc());
		return errorHandle(request,response,restRsp);
	}  
	
	/**
	 * 参数解析失败
	 * @param request
	 * @param response
	 * @param e
	 * @return
	 * @throws IOException 
	 */
	@ExceptionHandler(HttpMessageNotReadableException.class)
	public RestRsp httpMessageNotReadableException(HttpServletRequest request, HttpServletResponse response, HttpMessageNotReadableException e) throws IOException {
		RestRsp restRsp = new RestRsp();
		restRsp.setCode(Status.BAD_REQUEST_BODY.getCode());
		restRsp.setMsg(Status.BAD_REQUEST_BODY.getDesc());
		return errorHandle(request,response,restRsp);
//		return errorHandle(request,response,Messages.BAD_REQUEST_BODY);
	}  
	
	/**
	 * 参数校验失败
	 * @param request
	 * @param response
	 * @param e
	 * @return
	 * @throws IOException
	 */
	@ExceptionHandler(IllegalArgumentException.class)
	public RestRsp illegalArgumentException(HttpServletRequest request, HttpServletResponse response, IllegalArgumentException e) throws IOException {
		e.printStackTrace();
		RestRsp restRsp = new RestRsp();
		restRsp.setCode(Status.BAD_PARAM.getCode());
		restRsp.setMsg(Status.BAD_PARAM.getDesc());
		return errorHandle(request,response,restRsp);
//		return errorHandle(request,response,Messages.BAD_PARAM);
	} 
	
	
	/**
	 * 参数校验失败
	 * @param request
	 * @param response
	 * @param e
	 * @return
	 * @throws IOException 
	 */
	@ExceptionHandler(MethodArgumentTypeMismatchException.class)
	public RestRsp methodArgumentTypeMismatchException(HttpServletRequest request, HttpServletResponse response, MethodArgumentTypeMismatchException e) throws IOException {
		RestRsp restRsp = new RestRsp();
		restRsp.setCode(Status.BAD_PARAM.getCode());
		restRsp.setMsg(Status.BAD_PARAM.getDesc());
		return errorHandle(request,response,restRsp);
	}  
	
	/**
	 * 参数校验失败
	 * @param request
	 * @param response
	 * @param e
	 * @return
	 * @throws IOException 
	 */
	@ExceptionHandler(BindException.class)
	public RestRsp bindException(HttpServletRequest request, HttpServletResponse response, BindException e) throws IOException {
		RestRsp restRsp = new RestRsp();
		restRsp.setCode(Status.BAD_PARAM.getCode());
		restRsp.setMsg(Status.BAD_PARAM.getDesc());
		return errorHandle(request,response,restRsp);
	}  
	
	
	
	/**
	 * 请求方式不支持
	 * @param request
	 * @param response
	 * @param e
	 * @return
	 * @throws IOException 
	 */
	@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
	public RestRsp httpRequestMethodNotSupportedException(HttpServletRequest request, HttpServletResponse response, HttpRequestMethodNotSupportedException e) throws IOException {
		RestRsp restRsp = new RestRsp();
		restRsp.setCode(Status.REQUEST_METHOD_NOT_SUPPORT.getCode());
		restRsp.setMsg(Status.REQUEST_METHOD_NOT_SUPPORT.getDesc());
		return errorHandle(request,response,restRsp);
	}

	/**
	 * 不支持的媒体类型
	 * @param request
	 * @param response
	 * @param e
	 * @return
	 * @throws IOException 
	 */
	@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
	public RestRsp httpMediaTypeNotSupportedException(HttpServletRequest request, HttpServletResponse response, HttpMediaTypeNotSupportedException e) throws IOException {
		RestRsp restRsp = new RestRsp();
		restRsp.setCode(Status.MEDIA_TYPE_NOT_SUPPORTED.getCode());
		restRsp.setMsg(Status.MEDIA_TYPE_NOT_SUPPORTED.getDesc());
		return errorHandle(request,response,restRsp);
	}  
	

	/**
	 * 路径未找到
	 * @param request
	 * @param response
	 * @param e
	 * @return
	 * @throws IOException
	 */
	@ExceptionHandler(NoHandlerFoundException.class)
	public RestRsp noHandlerFoundException(HttpServletRequest request, HttpServletResponse response, NoHandlerFoundException e) throws IOException {
		RestRsp restRsp = new RestRsp();
		restRsp.setCode(Status.BAD_URL.getCode());
		restRsp.setMsg(Status.BAD_URL.getDesc());
		return errorHandle(request,response,restRsp);
	}  
	
	/**
	 * 业务异常
	 * @param request
	 * @param response
	 * @param e
	 * @return
	 * @throws IOException 
	 */
	@ExceptionHandler(ServiceException.class)
	public RestRsp serviceException(HttpServletRequest request, HttpServletResponse response, ServiceException e) throws IOException {
		return errorHandle(request,response,e.getErrorMessage());
	}  
	
  
	/**
	 * 服务器异常
	 * @param request
	 * @param response
	 * @param e
	 * @return
	 * @throws IOException 
	 */
	@ExceptionHandler(Exception.class)
	public RestRsp handleException(HttpServletRequest request, HttpServletResponse response, Exception e) throws IOException {
		e.printStackTrace();
		if(e instanceof ServiceException) {
			return errorHandle(request,response,((ServiceException)e).getErrorMessage());
		}
		RestRsp restRsp = new RestRsp();
		restRsp.setCode(Status.SERVER_ERROR.getCode());
		restRsp.setMsg(Status.SERVER_ERROR.getDesc());
		return errorHandle(request,response,restRsp);
	}  
}
